#include "../../afwApp.h"
#include <GL/glut.h>
#include <assert.h>

using namespace one_rag::App::impl;

one_rag::Core::MutableArray<GlutWindow*> GlutWindow::_map;


GlutWindow::GlutWindow():_wnd(0),_callbacks(0)
{

}

int GlutWindow::CreateWindow(const char* name)
{
  _wnd = glutCreateWindow(name);

  _map.SetAt(_wnd,this);

  return _wnd;
}

bool GlutWindow::Create(const char* name, int x, int y, int w, int h)
{
  assert(!_wnd);
  glutInitWindowPosition(x,y);
  if(w!=-1)
  glutInitWindowSize(w,h);
  return CreateWindow(name) != 0;
}

bool GlutWindow::Create(const char* name, ePositionType pos, int w, int h)
{
  assert(!_wnd);
  if(w!=-1)
    glutInitWindowSize(w,h);
  return CreateWindow(name) != 0;
}

bool GlutWindow::SetDelegate(GlutWindowDelegate* callbacks, unsigned flags)
{
  assert(!_callbacks);
  assert(callbacks);
  _callbacks = callbacks;

  if(flags == glutAllProcs)
    flags = glutDisplayProc|glutOverlayDisplayProc|glutMouseProc|glutReshapeProc;

  if(flags & glutDisplayProc)
    glutDisplayFunc(&OnDisplay);
  if(flags & glutOverlayDisplayProc)
    glutOverlayDisplayFunc(&OnOverlayDisplay);
  if(flags & glutReshapeProc )
    glutReshapeFunc(&OnReshape);

  return true;
}

void GlutWindow::OnDisplay()
{
  GlutWindow* self = _map[glutGetWindow()];
  if(self)
    self->_callbacks->OnDisplay();

  glutSwapBuffers();
}

void GlutWindow::OnOverlayDisplay()
{
  GlutWindow* self = _map[glutGetWindow()];
  if(self)
    self->_callbacks->OnOverlayDisplay();
}

void GlutWindow::OnReshape(int cx, int cy)
{
  GlutWindow* self = _map[glutGetWindow()];
  if(self)
    self->_callbacks->OnReshape(cx,cy);
}

void GlutWindow::PostRedisplay()
{
  glutSetWindow(_wnd);
  glutPostRedisplay();
}
